package json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import gson.GsonFactory;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author dushougudu
 */
@Slf4j
public class JsonTest {
    public static void main(String[] args) throws Exception {
//        parseArray();
//        parseObject();
        toJson();
    }

    public static void parseArray() {
        String jsonCase = "[{\"id\":10001,\"name\":\"小明\"},{\"id\":10002,\"name\":\"小李\"}]";

        // fastjson
        JSONArray jsonArray = JSON.parseArray(jsonCase);
        System.out.println(jsonArray);
        System.out.println(jsonArray.getJSONObject(0).getString("name"));
        System.out.println(jsonArray.getJSONObject(1).getString("name"));
        List<User> userList = JSON.parseArray(jsonCase, User.class);
        for (User u : userList) {
            System.out.println(u.toString());
        }

        // Gson
        JsonArray jsonArrayGson = new Gson().fromJson(jsonCase, JsonArray.class);
        System.out.println(jsonArrayGson);
        System.out.println(jsonArrayGson.get(0).getAsJsonObject().get("name").getAsString());
        System.out.println(jsonArrayGson.get(1).getAsJsonObject().get("name").getAsString());

        userList = new Gson().fromJson(jsonCase, new com.google.gson.reflect.TypeToken<List<User>>() {
        }.getType());
        for (User u : userList) {
            System.out.println(u.toString());
        }

        //jackson
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            userList = objectMapper.readValue(jsonCase, new com.fasterxml.jackson.core.type.TypeReference<List<User>>() {
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        for (User u : userList) {
            System.out.println(u.toString());
        }

    }

    @SneakyThrows
    public static void parseObject() {
        String json = "{\"birth\":\"2021-03-27 18:35:57\",\"like\":[],\"sex\":\"MAN\",\"name\":\"james\"}";

        //fastjson 容错好
        User user = JSON.parseObject(json, User.class);
        System.out.println("fastjson");
        System.out.println(user.getUserName());
        System.out.println(user.getBirth());
        System.out.println(user.getSex());

        //gson
        user = new Gson().fromJson(json, User.class);
        System.out.println("gson");
        System.out.println(user.getUserName());
        System.out.println(user.getBirth());
        System.out.println(user.getSex());

        //jackson
        ObjectMapper objectMapper = new ObjectMapper();
        user = objectMapper.readValue(json, User.class);
        System.out.println("jackson");
        System.out.println(user.getUserName());
        System.out.println(user.getBirth());
        System.out.println(user.getSex());
    }

    @SneakyThrows
    public static void toJson() {
        User user = new User();
        user.setBirth(new Date());
        user.setUserName("james");
        user.setSex(Sex.MAN);
        user.setLike(new ArrayList<>());
        user.setUUID("UUID-1111");

        //fastjson
        log.info("fastjson:{}",JSON.toJSONString(user));

        //gson
        Gson gson = new GsonBuilder().serializeNulls().create();
        log.info("gson:{}",gson.toJson(user));

        //jackson
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(Date.class, new BusinessDateCustomizeDeSerializer());
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.registerModule(javaTimeModule);
        log.info("jackson:{}",objectMapper.writeValueAsString(user));
    }

    public static void generic() {
        // 实体类
        User user = new User();
        user.setId(1L);
        user.setUserName("马云");
        List userList = Lists.newArrayList(user);

        //fastjson
        List<User> userListResultFastjson = JSONArray.parseArray(JSON.toJSONString(userList), User.class);
        List<User> userListResultFastjson2 = JSON.parseObject(JSON.toJSONString(userList), new TypeReference<List<User>>() {
        });
        System.out.println(userListResultFastjson);
        System.out.println("userListResultFastjson2" + userListResultFastjson2);

        //gson
        Gson gson = new Gson();
        List<User> userListResultGson = gson.fromJson(gson.toJson(userList), new TypeToken<List<User>>() {
        }.getType());
        System.out.println("userListResultGson" + userListResultGson);
    }

    public static void dateTrans() throws JsonProcessingException {
        User user = new User();
        user.setBirth(new Date());
        user.setUserName("james");
        user.setSex(Sex.MAN);

        // fastjson
        //QuoteFieldNames———-输出key时是否使用双引号,默认为true
        //WriteMapNullValue——–是否输出值为null的字段,默认为false
        //WriteNullNumberAsZero—-数值字段如果为null,输出为0,而非null
        //WriteNullListAsEmpty—–List字段如果为null,输出为[],而非null
        //WriteNullStringAsEmpty—字符类型字段如果为null,输出为”“,而非null
        //WriteNullBooleanAsFalse–Boolean字段如果为null,输出为false,而非null

        //自定义序列化 SerializeConfig serializeConfig = new SerializeConfig();
        //自定义反序列化 ParserConfig parserConfig = new ParserConfig();
        System.out.println(JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss"
                , SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty));

        // Gson
        //自定义序列化/反序列化 new GsonBuilder().registerTypeAdapter()
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        System.out.println(gson.toJson(user));

        //jackson  默认会输出null值的属性
        //使用注解 @JsonInclude(Include.NON_NULL)
        //Include.Include.ALWAYS 默认
        //Include.NON_DEFAULT 属性为默认值不序列化
        //Include.NON_EMPTY 属性为 空（“”） 或者为 NULL 都不序列化
        //Include.NON_NULL 属性为NULL 不序列化

        //SimpleModule module = new SimpleModule();
        //自定义序列化 module.addSerializer(Date.class, new JacksonCustomerDateJsonSerializer());
        //自定义反序列化 module.addDeserializer(Date.class, new JacksonCustomerDateJsonDeserializer());
        //mapper.registerModule(module);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        objectMapper.setDateFormat(dateFormat);
        System.out.println(objectMapper.writeValueAsString(user));
    }


}
